/**
 * Copyright (C) 2023 maminjie <canpool@163.com>
 * Copyright (C) 2017-2018 Uwe Kindler
 * SPDX-License-Identifier: LGPL-2.1
 **/

#include "QxDockElidingLabel.h"

#include <QMouseEvent>

QX_BEGIN_NAMESPACE

/**
 * Private data of public CClickableLabel
 */
struct DockElidingLabelPrivate {
    DockElidingLabel *_this;
    Qt::TextElideMode ElideMode = Qt::ElideNone;
    QString Text;
    bool IsElided = false;

    DockElidingLabelPrivate(DockElidingLabel *_public) : _this(_public)
    {
    }

    void elideText(int Width);

    /**
     * Convenience function to check if the
     */
    bool isModeElideNone() const
    {
        return Qt::ElideNone == ElideMode;
    }
};

void DockElidingLabelPrivate::elideText(int Width)
{
    if (isModeElideNone()) {
        return;
    }
    QFontMetrics fm = _this->fontMetrics();
    QString str = fm.elidedText(Text, ElideMode, Width - _this->margin() * 2 - _this->indent());
    if (str == "…") {
        str = Text.at(0);
    }
    bool WasElided = IsElided;
    IsElided = str != Text;
    if (IsElided != WasElided) {
        Q_EMIT _this->elidedChanged(IsElided);
    }
    _this->QLabel::setText(str);
}

DockElidingLabel::DockElidingLabel(QWidget *parent, Qt::WindowFlags f) : QLabel(parent, f), d(new DockElidingLabelPrivate(this))
{
}

DockElidingLabel::DockElidingLabel(const QString &text, QWidget *parent, Qt::WindowFlags f)
    : QLabel(text, parent, f), d(new DockElidingLabelPrivate(this))
{
    d->Text = text;
    internal::setToolTip(this, text);
}

DockElidingLabel::~DockElidingLabel()
{
    delete d;
}

Qt::TextElideMode DockElidingLabel::elideMode() const
{
    return d->ElideMode;
}

void DockElidingLabel::setElideMode(Qt::TextElideMode mode)
{
    d->ElideMode = mode;
    d->elideText(size().width());
}

bool DockElidingLabel::isElided() const
{
    return d->IsElided;
}

void DockElidingLabel::mouseReleaseEvent(QMouseEvent *event)
{
    Super::mouseReleaseEvent(event);
    if (event->button() != Qt::LeftButton) {
        return;
    }

    Q_EMIT clicked();
}

void DockElidingLabel::mouseDoubleClickEvent(QMouseEvent *ev)
{
    Q_UNUSED(ev)
    Q_EMIT doubleClicked();
    Super::mouseDoubleClickEvent(ev);
}

void DockElidingLabel::resizeEvent(QResizeEvent *event)
{
    if (!d->isModeElideNone()) {
        d->elideText(event->size().width());
    }
    Super::resizeEvent(event);
}

QSize DockElidingLabel::minimumSizeHint() const
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
    bool HasPixmap = !pixmap(Qt::ReturnByValue).isNull();
#else
    bool HasPixmap = (pixmap() != nullptr);
#endif
    if (HasPixmap || d->isModeElideNone()) {
        return QLabel::minimumSizeHint();
    }
    const QFontMetrics &fm = fontMetrics();
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
    QSize size(fm.horizontalAdvance(d->Text.left(2) + "…"), fm.height());
#else
    QSize size(fm.width(d->Text.left(2) + "…"), fm.height());
#endif
    return size;
}

QSize DockElidingLabel::sizeHint() const
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
    bool HasPixmap = !pixmap(Qt::ReturnByValue).isNull();
#else
    bool HasPixmap = (pixmap() != nullptr);
#endif
    if (HasPixmap || d->isModeElideNone()) {
        return QLabel::sizeHint();
    }
    const QFontMetrics &fm = fontMetrics();
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
    QSize size(fm.horizontalAdvance(d->Text), QLabel::sizeHint().height());
#else
    QSize size(fm.width(d->Text), QLabel::sizeHint().height());
#endif
    return size;
}

void DockElidingLabel::setText(const QString &text)
{
    d->Text = text;
    if (d->isModeElideNone()) {
        Super::setText(text);
    } else {
        internal::setToolTip(this, text);
        d->elideText(this->size().width());
    }
}

QString DockElidingLabel::text() const
{
    return d->Text;
}

QX_END_NAMESPACE
